#include "Server.hpp"
#include <memory>

void Uages()
{
    std::cerr << "Uages\n\t:  ./Server.exe port" << std::endl;
    std::cerr << std::endl;
}

bool cal(const Request &req, Response &resp)
{
    // req已经有结构化完成的数据啦，你可以直接使用
    resp.exitcode = OK;
    resp.result = OK;

    switch (req.op)
    {
    case '+':
        resp.result = req.x + req.y;
        break;
    case '-':
        resp.result = req.x - req.y;
        break;
    case '*':
        resp.result = req.x * req.y;
        break;
    case '/':
    {
        if (req.y == 0)
            resp.exitcode = DIV_ZERO;
        else
            resp.result = req.x / req.y;
    }
    break;
    case '%':
    {
        if (req.y == 0)
            resp.exitcode = MOD_ZERO;
        else
            resp.result = req.x % req.y;
    }
    break;
    default:
        resp.exitcode = OP_ERROR;
        break;
    }

    return true;
}

// 将业务处理和对应的IO处理分离
void calCulTes(ServerFile::Connection *conn)
{
    std::string onePackAge;
    while (ParseOnePackage(conn->_readbuffer, &onePackAge))
    {
        // 现在进行序列化和反序列化的处理，处理对象是onePackAge；
        std::string reqstr;
        if (!deLength(onePackAge, &reqstr))
            return;

        std::cout << "去掉报头的报文 \n"
                  << reqstr << std::endl;

        Request req;
        if (!req.deserialize(reqstr))
            return;

        Response resp;
        cal(req, resp);

        std::string respstr;
        resp.serialize(&respstr);
        std::string send_string = enLength(respstr);

        conn->_writebuffer += send_string;

        std::cout << "发送回去的---result" << send_string << std::endl;
        // 直接发出去，因为写时间就绪是常态，就算对方缓冲区满了，我们也有对应的策略
    }

    if (conn->_sender)
        conn->_sender(conn);
    // 经过分析，没发完就要把该写事件设为关心 , 发完了就要关闭写事件 （防止以前设置成写事件了）
    // 但是设为关心的接口在 Server.hpp类中怎么办 ， 答案：回指指针

//     if(!conn->_writebuffer.empty()) conn->_Sercon->enableReadWrite(conn,true,true);
//     else conn->_Sercon->enableReadWrite(conn,true,false);

}

// ./Server.exe port   //启动服务器
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Uages();
        exit(STARTINFORMATION_ERRON);
    }

    std::unique_ptr<ServerFile::Server> ser(new ServerFile::Server(calCulTes, atoi(argv[1])));

    ser->init();

    ser->disPatch();

    return 0;
}